package cn.bistu.cs.zszproject1;

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;

import android.view.Gravity;
import android.view.View;

import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;


public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    Button btn_0;
    Button btn_1;
    Button btn_2;
    Button btn_3;
    Button btn_4;
    Button btn_5;
    Button btn_6;
    Button btn_7;
    Button btn_8;
    Button btn_9;
    Button btn_point; //小数点
    Button btn_clear; //清除
    Button btn_del;   //删除
    Button btn_plus;
    Button btn_minus;
    Button btn_multiply;
    Button btn_divide;
    Button btn_equal;
    Button btn_left;
    Button btn_right;
    Button btn_change;
    Button btn_factorial;
    private TextView et_input;
    private StringBuilder pending = new StringBuilder();

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    private void initView() {
        btn_0 = (Button) findViewById(R.id.btn_0);
        btn_1 = (Button) findViewById(R.id.btn_1);
        btn_2 = (Button) findViewById(R.id.btn_2);
        btn_3 = (Button) findViewById(R.id.btn_3);
        btn_4 = (Button) findViewById(R.id.btn_4);
        btn_5 = (Button) findViewById(R.id.btn_5);
        btn_6 = (Button) findViewById(R.id.btn_6);
        btn_7 = (Button) findViewById(R.id.btn_7);
        btn_8 = (Button) findViewById(R.id.btn_8);
        btn_9 = (Button) findViewById(R.id.btn_9);
        btn_point = (Button) findViewById(R.id.btn_point);
        btn_clear = (Button) findViewById(R.id.btn_clear);
        btn_del = (Button) findViewById(R.id.btn_del);
        btn_plus = (Button) findViewById(R.id.btn_plus);
        btn_minus = (Button) findViewById(R.id.btn_minus);
        btn_multiply = (Button) findViewById(R.id.btn_multiply);
        btn_divide = (Button) findViewById(R.id.btn_divide);
        btn_equal = (Button) findViewById(R.id.btn_equal);
        et_input = (TextView) findViewById(R.id.et_input);
        btn_left = (Button) findViewById(R.id.btn_left);
        btn_right = (Button) findViewById(R.id.btn_right);
        btn_change = (Button) findViewById(R.id.btn_change);
        btn_factorial = (Button) findViewById(R.id.btn_factorial);

        btn_0.setOnClickListener(this);
        btn_1.setOnClickListener(this);
        btn_2.setOnClickListener(this);
        btn_3.setOnClickListener(this);
        btn_4.setOnClickListener(this);
        btn_5.setOnClickListener(this);
        btn_6.setOnClickListener(this);
        btn_7.setOnClickListener(this);
        btn_8.setOnClickListener(this);
        btn_9.setOnClickListener(this);
        btn_point.setOnClickListener(this);
        btn_plus.setOnClickListener(this);
        btn_equal.setOnClickListener(this);
        btn_minus.setOnClickListener(this);
        btn_multiply.setOnClickListener(this);
        btn_del.setOnClickListener(this);
        btn_divide.setOnClickListener(this);
        btn_clear.setOnClickListener(this);
        btn_divide.setOnClickListener(this);
        btn_left.setOnClickListener(this);
        btn_right.setOnClickListener(this);
        btn_change.setOnClickListener(this);
        btn_factorial.setOnClickListener(this);
    }

    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.btn_0:
                pending = pending.append("0");
                et_input.setText(pending);
                break;
            case R.id.btn_1:
                pending = pending.append("1");
                et_input.setText(pending);
                break;
            case R.id.btn_2:
                pending = pending.append("2");
                et_input.setText(pending);
                break;
            case R.id.btn_3:
                pending = pending.append("3");
                et_input.setText(pending);
                break;
            case R.id.btn_4:
                pending = pending.append("4");
                et_input.setText(pending);
                break;
            case R.id.btn_5:
                pending = pending.append("5");
                et_input.setText(pending);
                break;
            case R.id.btn_6:
                pending = pending.append("6");
                et_input.setText(pending);
                break;
            case R.id.btn_7:
                pending = pending.append("7");
                et_input.setText(pending);
                break;
            case R.id.btn_8:
                pending = pending.append("8");
                et_input.setText(pending);
                break;
            case R.id.btn_9:
                pending = pending.append("9");
                et_input.setText(pending);
                break;
            case R.id.btn_plus:
                if(pending.length()==0){
                    Toast.makeText(this,"加号前面无操作数",Toast.LENGTH_SHORT).show();
                }
                else if((pending.charAt(pending.length()-1)<'0'||pending.charAt(pending.length()-1)>'9'))
                    pending = pending.append("+ ");
                else
                    pending = pending.append(" + ");
                et_input.setText(pending);
                break;
            case R.id.btn_minus:
                if(pending.length()==0){
                    Toast.makeText(this,"减号前面无操作数",Toast.LENGTH_SHORT).show();
                }
                else if((pending.charAt(pending.length()-1)<'0'||pending.charAt(pending.length()-1)>'9'))
                    pending = pending.append("- ");
                else
                    pending = pending.append(" - ");
                et_input.setText(pending);
                break;
            case R.id.btn_multiply:
                if(pending.length()==0){
                    Toast.makeText(this,"乘号前面无操作数",Toast.LENGTH_SHORT).show();
                }
                else if((pending.charAt(pending.length()-1)<'0'||pending.charAt(pending.length()-1)>'9'))
                    pending = pending.append("* ");
                else
                    pending = pending.append(" * ");
                et_input.setText(pending);
                break;
            case R.id.btn_divide:
                if(pending.length()==0){
                    Toast.makeText(this,"除号前面无操作数",Toast.LENGTH_SHORT).show();
                }
                else if((pending.charAt(pending.length()-1)<'0'||pending.charAt(pending.length()-1)>'9'))
                    pending = pending.append("/ ");
                else
                    pending = pending.append(" / ");
                et_input.setText(pending);
                break;
            case R.id.btn_factorial:
                if(isFactorial()){
                    pending.append(" ! ");
                }else{
                    Toast.makeText(this,"阶乘符号使用错误",Toast.LENGTH_SHORT).show();
                }
                et_input.setText(pending);
                break;
            case R.id.btn_point:
                if (doublePoints())
                    pending = pending.append(".");
                else
                    Toast.makeText(this,"不允许一个数据输入两个小数点",Toast.LENGTH_SHORT).show();
                et_input.setText(pending);
                break;
            case R.id.btn_right:// )右括号
                if(pending.indexOf("(")==-1){
                    Toast.makeText(this,"前面无左括号",Toast.LENGTH_SHORT).show();
                }else{
                    pending = pending.append(" ) ");et_input.setText(pending);
                }
                break;
            case R.id.btn_left:// （左括号

                if(pending.length()==0||(pending.charAt(pending.length()-1)<'0'||pending.charAt(pending.length()-1)>'9')){
                    pending = pending.append("( ");
                }else{
                    pending = pending.append(" ( ");
                }
                et_input.setText(pending);
                break;
            case R.id.btn_change:
                if(pending.charAt(0)=='-'){
                    pending = new StringBuilder(pending.substring(1));
                }else{
                    pending = new StringBuilder("-" + pending);
                }
                et_input.setText(pending);
                break;
            case R.id.btn_del: //删除
                if (pending.length() != 0) {
                    pending = pending.delete(pending.length() - 1, pending.length());
                    et_input.setText(pending);
                }
                break;
            case R.id.btn_clear: //清空
                pending = pending.delete(0, pending.length());
                et_input.setText(pending);
                break;
            case R.id.btn_equal: // =等于
                //如果只输入一个数，那么不变
                if (oneData()){
                    et_input.setText(pending);
                }
                else if ((pending.length() > 1)&&check()) {
                    Calculate calculate = new Calculate(pending);
                    String result=null;
                    try {
                        //中缀表达式转后缀表达式
                        StringBuilder s = calculate.infixTOSuffix();
                        //后缀表达式计算结果
                        double num = Double.parseDouble(calculate.compute());
                        int pointLength = getDecimalLength();
                        //System.out.println(pointLength);
                        String format;
                        if(pointLength>0&&((num-0)*(num-0))>0.00001){
                            format = "0.";
                            for (int i=0;i<pointLength;i++){
                                format += "0";
                            }
                        }else if(pointLength==0&&((num-Math.floor(num))*(num-Math.floor(num)))>0.00001){
                            format = "0.000000";
                        }
                        else
                            format = "#";
                        DecimalFormat df = new DecimalFormat(format);
                        result = df.format(num);
                        //result = String.format("%.f",pointLength,Double.parseDouble(calculate.compute()));
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        result = "出错";

                    }
                    et_input.setText(pending + " = " + result);
                    pending = pending.delete(0, pending.length());
                    if (Character.isDigit(result.charAt(0))) {
                        pending = pending.append(result);
                    }
                }
                break;
            default:
                break;
        }

    }
    //阶乘，正整数 （n-m）！
    private boolean isFactorial(){
        boolean res = true;
        if(pending.charAt(0)=='-'||pending.indexOf(".")!=-1){
            res = false;
            Toast.makeText(this,"该数必须是正整数",Toast.LENGTH_SHORT).show();
        }else if(pending.charAt(pending.length()-1)==')'){
            int pos = pending.indexOf("(");
            StringBuilder ss = new StringBuilder(pending.substring(pos,pending.length()-1));
            Calculate c1 = new Calculate(ss);
            c1.infixTOSuffix();
            if(Double.parseDouble(c1.compute())<0){
                res = false;
                Toast.makeText(this,"括号内的数必须是正整数",Toast.LENGTH_SHORT).show();
            }
        }
        return  res;
    }

    //获取浮点数的小数的位数
    private  int getDecimalLength(){
        int res = 0;
        String []arr = pending.toString().split(" ");
        for(String s:arr){
            if(s.matches("-?[0-9]+.[0-9]*")){
                int pointPos = s.indexOf(".");
                res = s.length()-1-pointPos;
            }
        }
        return res;
    }

    //只输入一个数据就“=”
    private boolean oneData(){
        boolean res = true;
        if(pending.length()==1){
            return true;
        }
        String[] strings = pending.toString().split(" ");
        for(String s:strings){
            if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")||s.equals("!")){
                res = false;
            }
        }
        return res;
    }

    private boolean doublePoints(){
        boolean res = false;
        int point1 = pending.indexOf(".");
        int point2 = pending.length();
        if(point1!=-1){
            for (int i=point1+1;i<point2;i++){
                if(pending.charAt(i)<'0'||pending.charAt(i)>'9'){
                    res = true;
                    break;
                }
            }
        } else{
            res = true;
        }
        return res;
    }
    private boolean check(){
        boolean res = true;
        //除数的位置
        int divPos = pending.indexOf("/");
        //除数不能为0
        if(divPos>0&&pending.charAt(divPos+2)=='0'){
            res = false;
            Toast.makeText(this, "除数不能为0", Toast.LENGTH_SHORT).show();
        }
        //不能有两个运算符相连
        //String []strings = {"+","-","*","/"};
        Map<Character, Integer> map = new HashMap<Character, Integer>(){{
            put('+',0);
            put('-',1);
            put('*',2);
            put('/',3);
        }};
        for (Character key:map.keySet()){
            int pos = pending.indexOf(String.valueOf(key));

            if(pos!=-1 && map.containsKey(pending.charAt(pos+2))){
                res = false;
                Toast.makeText(this,"运算符不能连续出现",Toast.LENGTH_SHORT).show();
                break;
            }
        }
        return res;
    }

//    private boolean judje1() {
//        String a = "+-*/.";
//        int[] b = new int[a.length()];
//        int max;
//        for (int i = 0; i < a.length(); i++) {
//            String c = "" + a.charAt(i);
//            b[i] = pending.lastIndexOf(c);
//        }
//        Arrays.sort(b);
//        if (b[a.length() - 1] == -1) {
//            max = 0;
//        } else {
//            max = b[a.length() - 1];
//        }
//        if (pending.indexOf(".", max) == -1) {
//            return true;
//        } else {
//            return false;
//        }
//    }
//    private int judje2(){
//        int a=0,b=0;
//        for(int i = 0 ; i < pending.length() ;i++){
//            if(pending.charAt(i)=='(' ) {
//                a++;
//            }
//            if(pending.charAt(i)==')' ) {
//                b++;
//            }
//        }
//        if(a == b)
//            return 0;
//        if(a > b)
//            return 1;
//        return 2;
//    }




}
